package com.lsl.rdf.utils;

import com.lsl.rdf.annotation.LockTarget;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.util.Assert;

import java.lang.reflect.Parameter;
import java.util.Objects;

/**
 * Created by lsl on 2021/4/27.
 */
public class LockAopUtil {

    /**
     * 根据切入点和el表达式解析所名称
     *
     * @param joinPoint 切入点对象
     * @param el        el表达式
     * @return lockName
     */
    public static String getLockName(ProceedingJoinPoint joinPoint, String el) {
        Assert.notNull(joinPoint, "LockAopUtil.getLockName joinPoint is null");

        Object[] args = joinPoint.getArgs();

        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Parameter[] parameters = methodSignature.getMethod().getParameters();

        String lockName = methodSignature.getDeclaringType().getName() + "_" + methodSignature.getMethod().getName();

        if (Objects.nonNull(args) && args.length > 0 && !"".equals(el)) {
            EvaluationContext context = new StandardEvaluationContext();
            SpelExpressionParser parser = new SpelExpressionParser();

            for (int i = 0; i < parameters.length; i++) {
                LockTarget lockBean = parameters[i].getAnnotation(LockTarget.class);
                if (Objects.nonNull(lockBean)) {
                    String value = lockBean.value();
                    context.setVariable(value, args[i]);
                }
            }

            Object parserVal = parser.parseExpression(el).getValue(context);
            if (Objects.nonNull(parserVal)) {
                lockName += ":" + parserVal.toString();
            }
        }
        return lockName;
    }
}
